
/**
 * a generic Node implementation for binary trees
 * @param <T> Generic type.
 * @author Lukas Koell
 * @author David Medenjak
 * @author Johannes Riedmann
 */
public class Node<T> {

    /**
     * References to it's parent node and subnodes.
     */
    private Node<T> parent;
    private Node<T> leftchild;
    private Node<T> rightchild;
    /**
     * Label / Value of the node.
     */
    private T value;

    /**
     * Constructor
     * @param value generic value to save in the node.
     * @param parent Parent node.
     * @param leftchild Left child.
     * @param rightchild Right child.
     */
    public Node(T value, Node<T> parent, Node<T> leftchild, Node<T> rightchild) {
        this.parent = parent;
        this.leftchild = leftchild;
        this.rightchild = rightchild;
        this.value = value;
    }

    /**
     * @return the nodes parent, null if no parent is set
     */
    public Node<T> getParent() {
        return parent;
    }

    /**
     * sets the elements parent
     * @param parent
     */
    public void setParent(Node<T> parent) {
        this.parent = parent;
    }

    /**
     * @return the nodes left child, null if none is set
     */
    public Node<T> getLeftChild() {
        return leftchild;
    }

    /**
     * sets the left child of the node
     * @param leftchild
     */
    public void setLeftChild(Node<T> leftchild) {
        this.leftchild = leftchild;
    }

    /**
     * @return the right child of the node, null if none is set
     */
    public Node<T> getRightChild() {
        return rightchild;
    }

    /**
     * sets the right child of the node
     * @param rightchild
     */
    public void setRightChild(Node<T> rightchild) {
        this.rightchild = rightchild;
    }

    /**
     * @return the nodes actual value of type T
     */
    public T getValue() {
        return value;
    }

    /**
     * recursively going through the nodes to find a node containing the param node's value
     * @param node value of node we are searching
     * @return true if node contains node with given value
     */
    public boolean contains(T node) {
        if (this.value.equals(node)) {
            return true;
        } else {
            if (this.getLeftChild() != null) {
                if (this.leftchild.contains(node)) {
                    return true;
                }
            }
            if (this.getRightChild() != null) {
                if (this.rightchild.contains(node)) {
                    return true;
                }
            }
        }
        return false;
    }
}
